<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>

  <script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
  <script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"></script>
  <script src="https://d3js.org/d3.v5.min.js"></script>

  <style>
    ul {
      list-style: none;
      padding: 0;
      position: relative;
    }

    ul li {
      height: 20px;
      line-height: 20px;
      width: 150px;
      background-color: bisque;
      margin-bottom: 4px;
      font-size: 14px;
      border-radius: 10px;
      padding-left: 10px;
      border: 1px solid brown;
      color: #666;
      position: absolute;
      transition-duration: 0.3s;
      transition-property: top;
      transition-timing-function: ease-in-out;
    }

    ul li.lead {
      background-color: burlywood;
    }

    @keyframes menuFadeOut {
      0% {
        opacity: 1;
      }

      50% {
        opacity: .3;
        top: 112px;
      }

      100% {
        opacity: 0;
        top: 112px;
        display: none;
      }
    }

    @keyframes menuFadeIn {
      0% {
        display: none;
        opacity: 1;
        top: 168px;
      }

      80% {
        display: block;
        opacity: .7;
        top: 140px;
      }

      100% {
        top: 140px;
      }
    }
  </style>
</head>

<body>
  <div id="app">
    <ul>
    </ul>
    <div style="position:fixed;bottom: 60px;">
      <input type="text" style="width:90px;" placeholder="序号" v-model="leadIndex">
      <button @click="racking">上移排名</button>
      <input type="text" style="width: 120px;margin-left: 20px;" placeholder="填写菜单名称" v-model="newMenuName">
      <button @click="adding">新增菜品</button>

      <button @click="parseWsData" style="margin-left: 20px;">推送数据</button>
    </div>
  </div>
</body>
<script>
  let menuList = [{
      order: 1,
      oid: 26222816776945672,
      menuName: '麻婆豆腐',
      top: 0
    },
    {
      order: 2,
      oid: 26222816776945664,
      menuName: '酸菜鱼',
      top: 0
    },
    {
      order: 3,
      oid: 26222816776945673,
      menuName: '酸辣土豆丝',
      top: 0
    },
    {
      order: 4,
      oid: 26222816776945666,
      menuName: '肉沫蒸蛋',
      top: 0
    },
    {
      order: 5,
      oid: 26222816776945674,
      menuName: '酸辣鸡杂',
      top: 0
    },
    {
      order: 6,
      oid: 26222816799945674,
      menuName: '隐藏菜品',
      top: 0
    }
  ];

  let responseList = [
    // {
    //   order: 3,
    //   oid: 26222816776945672,
    //   menuName: '麻婆豆腐',
    //   top: 0
    // }
    {
      order: 1,
      oid: 26159130733446061,
      menuName: '农家小炒肉',
      top: 0,
      situation: 'init'
    },
    // {
    //   order: 2,
    //   oid: 26222816776945666,
    //   menuName: '肉沫蒸蛋',
    //   top: 0
    // },
    // {
    //   order: 3,
    //   oid: 26222816776945665,
    //   menuName: '炖猪蹄',
    //   top: 0
    // },
    // {
    //   order: 4,
    //   oid: 26222816776945664,
    //   menuName: '酸菜鱼',
    //   top: 0
    // },
    // {
    //   order: 5,
    //   oid: 26222816776945667,
    //   menuName: '萝卜牛腩',
    //   top: 0
    // }
  ];

  let backgroundList = [];

  var vm = new Vue({
    el: '#app',
    data() {
      return {
        leadIndex: 5,
        newMenuName: '窑鸡'
      }
    },
    methods: {
      domSituation: function ($item) {
        let situation = null;
        let domOrder = parseInt($item.attr('data-order'));
        responseList.forEach((resItem, i) => {
          let resItemOrder = resItem.order;
          if (domOrder === resItemOrder) {
            return situation = 'static';
          } else if (domOrder > resItemOrder) {
            return situation = 'climb';
          } else if (domOrder < resItemOrder) {
            return situation = 'slide';
          }

          if (situation == 'slide' && resItemOrder === responseList.length) {
            return situation = 'out';
          }
        })
        return situation;
      },
      whatSituation: function (menu, i) {
        let situation = 'push';
        
        if(!backgroundList){
          // 首秀时，以DOM情况为判断
          $('ul li').each((index, item) => {
            // id
            let domOid = $(item).attr('data-oid');
            // 序号
            let idx = parseInt($(item).attr('data-order'));
            
            if (menu.oid == domOid && idx < $('li').length) {
              // 如果是在队列中的元素
              if (i == idx) {
                // 且指定移动位置，和当前位置一样，则为停止
                situation = 'static';
                // 同时将当前DOM放入到backgrundList中
                $('ul li').each((dindex,ditem) => {
                  // backgroundList.push({})
                });
              } else if (i < idx) {
                // 指定位置比当前位置高(小)，则需要攀爬
                situation = 'climb';
              }
            }
          });
        }
        return situation;
      },
      slide: function ($item) {
        let selfOrder = parseInt($item.attr('data-order'));
        let targetOrder = selfOrder + 1;
        console.log('selfOrder:' + selfOrder, 'targetOrder:' + targetOrder);

        $('li').each((index, menuItem) => {
          let $menuItem = $(menuItem);
          let o = parseInt($menuItem.attr('data-order'));

          if (o === selfOrder) {
            // 自己的下移
            $menuItem.attr('data-order', targetOrder).animate({
              top: targetOrder * 28 + 'px'
            }, 1000);
          } else if (o === targetOrder) {
            // 目标上移
            $menuItem.attr('data-order', selfOrder).animate({
              top: selfOrder * 28 + 'px'
            }, 1000);
          } else {
            $menuItem.delay(1000)
          }
        });

        // $.queue($item, 'fx', function () {
        //   console.log('animate end')
        //   this.doAnimate($item);
        // });
        $item.queue(() => {
          console.log('animate end');
          // this.doAnimate($item);
        })
      },
      climb: function (obj) {
        let self = this;
        let targetIndex = obj.order - 1;
        let selfIndex = obj.order;

        $('li').each((index, item) => {
          let $item = $(item);
          let i = parseInt($item.attr('data-order'));

          if (i === selfIndex) {
            // 自己的上移
            $item.attr('data-order', selfIndex - 1).animate({
              top: (selfIndex - 1) * 28 + 'px'
            }, 1000);
          } else if (i === targetIndex) {
            // 目标下移
            $item.attr('data-order', selfIndex).animate({
              top: selfIndex * 28 + 'px'
            }, 1000);
          } else {
            $item.delay(1000)
          }
        });
      },
      push: function (obj) {
        let domLenth = $('li').length;

        $('li').each((index, item) => {
          let $item = $(item);
          let i = parseInt($item.attr('data-order'));

          // 新增元素上移
          if (i === domLenth) {
            let top = (domLenth - 1) * 28;
            $item.attr('top', top)
              .attr('data-order', domLenth - 1)
              .attr('data-oid', obj.oid)
              .text(obj.menuName)
              .css({
                'display': 'block'
              });
            $item.animate({
              'opacity': 1,
              'top': top + 'px'
            }, 1000);
          }
          // 末端元素下移
          else if (i === domLenth - 1) {
            let top = domLenth * 28;
            $item.attr('top', top);
            $item.attr('data-order', domLenth).animate({
              'display': 'none',
              'opacity': 0,
              'top': top + 'px'
            }, 1000);
          }
          // 其他元素静止不动
          else {
            $item.delay(1000);
          }
        });
      },
      racking: function () {
        let self = this;
        let moveIndex = self.leadIndex - 1;

        if (self.leadIndex >= 2) {

          $('li').each((index, item) => {
            let $item = $(item);
            let i = parseInt($item.attr('data-order'));

            if (i === self.leadIndex) {
              // 选中的上移
              $item.attr('data-order', self.leadIndex - 1).animate({
                top: (self.leadIndex - 1) * 28 + 'px'
              }, 1000);
            } else if (i === (self.leadIndex - 1)) {
              // 目标下移
              $item.attr('data-order', self.leadIndex).animate({
                top: self.leadIndex * 28 + 'px'
              }, 1000);
            } else {
              $item.delay(1000)
            }
          });

        } else {
          alert('你要上天啊？');
        }

        self.leadIndex = moveIndex;
      },
      init: function () {
        menuList.forEach((menuItem, i) => {
          let $menuItem = $('<li>')
            .text(menuItem.menuName)
            .css({
              'top': menuItem.order * 28 + 'px'
            })
            .attr('data-order', menuItem.order)
            .attr('data-oid', menuItem.oid);

          if (i == menuList.length - 1) {
            $menuItem.css({
              'display': 'none'
            })
          }

          $('ul').append($menuItem);
        });
      },
      adding: function () {
        let domLenth = $('li').length;
        $('li').each((index, item) => {
          let $item = $(item);
          let i = parseInt($item.attr('data-order'));

          // 新增元素上移
          if (i === domLenth) {
            let top = (domLenth - 1) * 28;
            $item.attr('top', top)
              .attr('data-order', domLenth - 1)
              .attr('data-oid', new Date().getTime())
              .text(this.newMenuName)
              .css({
                'display': 'block'
              });
            $item.animate({
              'opacity': 1,
              'top': top + 'px'
            }, 1000);
          }
          // 末端元素下移
          else if (i === domLenth - 1) {
            let top = domLenth * 28;
            $item.attr('top', top);
            $item.attr('data-order', domLenth).animate({
              'display': 'none',
              'opacity': 0,
              'top': top + 'px'
            }, 1000);
          } else {
            // 其他元素静止不动
            $item.delay(1000);
          }
        });
      },
      parseWsData: function () {
        // 2. 遍历数组，和DOM对比，获取situation（static-静止/climb-攀爬/push-推挤）
        // let $list = $('li');
        // console.log($('li').eq(0),$('li')[0])
        // this.doAnimate($($('li')[0]));
        // responseList.forEach((menu, i) => {
          let menu = responseList[0];
          do {
            let situation = this.whatSituation(menu, 1);
            switch (situation) {
              case 'push':
                this.push(menu);
                break;
              case 'climb':
                this.climb(menu);
                break;
              default:
                break;
            }
          } while (this.whatSituation(menu, 1) !== 'static');
        // });
      },
      doAnimate: function ($item) {
        let s = this.domSituation($item);
        console.log(s);
        switch (s) {
          // case 'climb':
          //   this.climb($item)
          //   break;
          case 'slide':
            this.slide($item)
            break;
            // case 'out':
            //   this.out($item)
            //   break;
          default:
            break;
        }
      }
    },
    mounted() {
      this.init();


    }
  })
</script>

</html>